//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.ManagementStudioModels
{
    using SR = Microsoft.Research.DataLayer;
    using System.ComponentModel;
    using System;
    using System.Collections.ObjectModel;

    /// <summary>
    /// The business object representation for the type initializer.
    /// </summary>
    public class TypeInitializerModel : BaseRegMgrModel
    {
        #region Private variables

        private static Guid parentGuid = Guid.NewGuid();

        private string author;

        private string relatedType;

        private bool completeTypeInitializerModel;

        #endregion Private variables

        #region Properties

        /// <summary>
        /// Gets or sets the assembly.
        /// </summary>
        /// <value>The assembly.</value>
        public string Assembly { get; set; }

        /// <summary>
        /// Gets or sets the class.
        /// </summary>
        /// <value>The class.</value>
        public string Class { get; set; }
        
        /// <summary>
        /// Gets or sets the type of the runtime.
        /// </summary>
        /// <value>The type of the runtime.</value>
        public string RuntimeType { get; set; }
        
        /// <summary>
        /// Gets or sets the author.
        /// </summary>
        /// <value>The author.</value>
        public string Author
        {
            get
            {
                return this.author;
            }
            set
            {
                this.author = value;
                this.RaisePropertyChanged("Author");
            }
        }

        /// <summary>
        /// Gets or sets the type of the related.
        /// </summary>
        /// <value>The type of the related.</value>
        public string RelatedType
        {
            get
            {
                return this.relatedType;
            }
            set
            {
                this.relatedType = value;
                this.RaisePropertyChanged("RelatedType");
            }
        }

        /// <summary>
        /// Gets the related workflows.
        /// </summary>
        /// <value>The related workflows.</value>
        public ObservableCollection<WorkflowViewModel> RelatedWorkflows { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether complete type initializer model.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if complete type initializer model; otherwise, <c>false</c>.
        /// </value>
        public bool CompleteTypeInitializerModel
        {
            get
            {
                return this.completeTypeInitializerModel;
            }
            set
            {
                this.completeTypeInitializerModel = value;
                this.RaisePropertyChanged("CompleteTypeInitializerModel");
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance has related workflows.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has related workflows; otherwise, <c>false</c>.
        /// </value>
        public bool HasRelatedWorkflows
        {
            get
            {
                bool hasRelatedWfs = false;
                if (this.RelatedWorkflows != null && this.RelatedWorkflows.Count > 0)
                {
                    hasRelatedWfs = true;
                }

                return hasRelatedWfs;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance has no related workflows.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has no related workflows; otherwise, <c>false</c>.
        /// </value>
        public bool HasNoRelatedWorkflows
        {
            get
            {
                return !this.HasRelatedWorkflows;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is deleted.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is deleted; otherwise, <c>false</c>.
        /// </value>
        public bool IsDeleted { get; set; }

        /// <summary>
        /// Overridden tostring method. For automation Ids.
        /// </summary>
        /// <returns>The string representation of the object.</returns>
        public override string ToString()
        {
            if (!string.IsNullOrEmpty(this.Name))
            {
                return this.Name;
            }
            return base.ToString();
        }
        #endregion Properties

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerModel"/> class.
        /// </summary>
        /// <param name="typeInit">The registry object.</param>
        public TypeInitializerModel(SR.TypeInitializer typeInit)
        {
            this.Update(typeInit);
            this.CompleteTypeInitializerModel = true;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerModel"/> class.
        /// This will be lightweight instance containing only the name and label.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="label">The label.</param>
        public TypeInitializerModel(string name, string label)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(name.Trim()))
            {
                throw new ArgumentNullException("name");
            }

            this.Name = name.Trim();
            this.Label = (string.IsNullOrEmpty(label) || string.IsNullOrEmpty(label.Trim())) ? this.Name : label.Trim();
            this.Id = TypeInitializerModel.parentGuid;
            this.CompleteTypeInitializerModel = false;
        }

        #endregion Constructor

        #region Public Methods

        /// <summary>
        /// Updates the model with the specified type intializer.
        /// </summary>
        /// <param name="typeInit">The typeInitializer.</param>
        public void Update(SR.TypeInitializer typeInit)
        {
            if (typeInit != null)
            {
                this.Name = typeInit.Name;
                this.Label = this.Name;
                this.RelatedType = typeInit.RelatedType.TypeName;
                this.Id = ((SR.IObject)typeInit).ID;
                this.Assembly = typeInit.AssemblyName;
                this.Class = typeInit.ClassName;
                this.Author = typeInit.Author;
                this.RuntimeType = typeInit.RuntimeType.ToString();
                this.CreatedBy = typeInit.Created.User;
                this.CreatedDate = typeInit.Created.When;
                this.LastModifiedBy = typeInit.Updated.User;
                this.LastModifiedTime = typeInit.Updated.When;
                this.IsDeleted = typeInit.IsDeleted;
            }
        }

        /// <summary>
        /// Updates the specified model.
        /// </summary>
        /// <param name="model">The model.</param>
        public override void Update(BaseRegMgrModel model)
        {
            TypeInitializerModel typeInitModel = model as TypeInitializerModel;
            if (typeInitModel != null)
            {
                this.Author = typeInitModel.Author;
                this.CreatedBy = typeInitModel.CreatedBy;
                this.CreatedDate = typeInitModel.CreatedDate;
                this.LastModifiedBy = typeInitModel.LastModifiedBy;
                this.LastModifiedTime = typeInitModel.LastModifiedTime;
                this.IsDeleted = typeInitModel.IsDeleted;
            }
        }

        #endregion Public Methods
    }
}
